/**
 * @Author       : Hejh(3010733382@qq.com)
 * @Version      : V1.0
 * @Date         : 2024-02-16 09:51:02
 * @Description  : 日志接口控制器
 */
const { Op } = require('sequelize')
const parser = require('ua-parser-js')
const { SystemLog } = require('@/framework/mongoose')
const R = require('@/models/Response')
const { User } = require('@/models/model')

/**
 * 列表查询日志接口
 * @param {*} ctx
 * @returns
 */
module.exports.listLog = async (ctx) => {
  const { page, pageSize, type, userId, startTime, endTime } = ctx.newQuery

  const whereCondition = {
    createTime: {}
  }
  if (type) {
    whereCondition.type = type
  } else {
    whereCondition.type = { $nin: ['http.log', 'http.fail', 'system.error'] }
  }

  if (userId !== undefined) {
    whereCondition.userId = userId
  }

  if (startTime !== undefined) {
    whereCondition.createTime = { ...whereCondition.createTime, $gt: startTime }
  }

  if (endTime !== undefined) {
    whereCondition.createTime = { ...whereCondition.createTime, $lt: endTime }
  }

  // console.log(whereCondition)
  if (!Object.keys(whereCondition.createTime).length) {
    delete whereCondition.createTime
  }

  const total = await SystemLog.countDocuments(whereCondition) // 获取总记录数
  const pages = Math.ceil(total / pageSize) // 计算总页数
  let logs = await SystemLog.find(whereCondition)
    .skip((page - 1) * pageSize) // 计算偏移量
    .limit(pageSize)
    .sort({ createTime: -1 })
    .lean() // 设置每页数量

  const myUserIds = logs.map((item) => item.userId).filter((v) => !!v)

  const users = await User.findAll({
    attributes: ['id', 'username', 'avator'],
    where: {
      id: {
        [Op.in]: myUserIds
      }
    }
  })

  logs = logs.map((item) => {
    return {
      ...item,
      uaParse: parser(item.ua),
      id: item._id,
      user: users.find((item2) => item2.id === item.userId) || undefined
    }
  })

  // 根据userId查询出用户信息

  ctx.body = R.success({
    page,
    pageSize,
    total,
    pages,
    items: logs
  })
}

/**
 * 列表查询用户日志接口
 * @param {*} ctx
 * @returns
 */
module.exports.listUserLog = async (ctx) => {
  const { page, pageSize, type } = ctx.newQuery

  const whereCondition = {
    userId: ctx.user.id
  }
  if (type) {
    whereCondition.type = type
  } else {
    whereCondition.type = { $nin: ['http.log', 'http.fail', 'system.error'] }
  }

  const total = await SystemLog.countDocuments(whereCondition) // 获取总记录数
  const pages = Math.ceil(total / pageSize) // 计算总页数
  let logs = await SystemLog.find(whereCondition)
    .skip((page - 1) * pageSize) // 计算偏移量
    .limit(pageSize)
    .sort({ createTime: -1 })
    .lean() // 设置每页数量

  const user = await User.findByPk(BigInt(ctx.user.id), {
    attributes: ['id', 'username', 'avator']
  })

  logs = logs.map((item) => {
    return {
      ...item,
      uaParse: parser(item.ua),
      id: item._id,
      user
    }
  })

  // 根据userId查询出用户信息
  ctx.body = R.success({
    page,
    pageSize,
    total,
    pages,
    items: logs
  })
}

/**
 * 列表查询用户的登录设备,分类依据的话是IP和ua不同
 * @param {*} ctx
 * @returns
 */
module.exports.listLogDevice = async (ctx) => {
  const { page, pageSize } = ctx.newQuery

  const whereCondition = {
    userId: ctx.user.id,
    type: 'user.login'
  }

  const groupCondition = {
    _id: { ua: '$ua', ip: '$ip' },
    latest_create_time: { $max: '$createTime' },
    recordId: { $first: '$_id' }
  }

  // 进行聚合查询
  const result = await SystemLog.aggregate([
    {
      $match: whereCondition // 添加查询条件
    },
    {
      $group: groupCondition
    },
    {
      $count: 'totalDevices' // 统计不同设备的数量
    }
  ])

  const total = result.length > 0 ? result[0].totalDevices : 0 // 获取总记录数
  const pages = Math.ceil(total / pageSize) // 计算总页数

  let logs = await SystemLog.aggregate([
    {
      $match: whereCondition // 添加查询条件
    },
    {
      $group: groupCondition
    },
    {
      $project: {
        _id: 0,
        ua: '$_id.ua',
        ip: '$_id.ip',
        createTime: '$latest_create_time',
        id: '$recordId'
      }
    },
    {
      $skip: (page - 1) * pageSize
    },
    {
      $limit: pageSize
    }
  ])

  const user = await User.findByPk(BigInt(ctx.user.id), {
    attributes: ['id', 'username', 'avator']
  })

  logs = logs.map((item) => {
    return {
      ...item,
      uaParse: parser(item.ua),
      user
    }
  })

  // 根据userId查询出用户信息
  ctx.body = R.success({
    page,
    pageSize,
    total,
    pages,
    items: logs
  })
}
